#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2016-2018, Niklas Hauser
# Copyright (c) 2017, Fabian Greif
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

def init(module):
    module.name = ":platform:flash"
    module.description = "Flash Memory"

def prepare(module, options):
    device = options[":target"]
    if device.identifier.family not in ["g0","g4", "f1", "f4"]:
        return False
    if not device.has_driver("flash:stm32*"):
        return False

    module.depends(":cmsis:device", ":platform:rcc",
                   ":architecture:register")
    return True

def build(env):
    target = env[":target"].identifier
    memories = listify(env[":target"].get_driver("core")["memory"])
    flash = next(filter(lambda m: m["name"] == "flash", memories))

    dual_bank = False
    family = target.family
    busy_bit = "FLASH_SR_BSY"
    ftype = "page"
    if target.family in ["f4"]:
        block_shift = 17
        ftype = "sector"
    elif target.family in ["f1"]:
        if target.name in  ["05", "07"] or int(flash["size"]) >= 262144:
            block_shift = 11
        else:
            block_shift = 10
    elif target.family in ["g0"]:
        busy_bit = "FLASH_SR_BSY1"
        block_shift = 11
        if target.name[0] in ["b", "c"]:
            dual_bank = "FLASH_OPTR_DUAL_BANK"
    elif target.family in ["g4"]:
        block_shift = 11
        # Only Cat3 devices have dual bank, so g47x or g48x
        if target.name[0] in ["7", "8"]:
            dual_bank = "FLASH_OPTR_DBANK"
            block_shift = "(FLASH->OPTR & FLASH_OPTR_DBANK ? 11 : 12)"

    env.substitutions = {
        "start": int(flash["start"], 16),
        "size": int(flash["size"]),
        "type": ftype,
        "shift": block_shift,
        "has_sectors": ftype == "sector",
        "busy_bit": busy_bit,
        "family": family,
        "dual_bank": dual_bank
    }
    env.outbasepath = "modm/src/modm/platform/flash"
    env.template("flash.hpp.in")
    env.template("flash.cpp.in")
